/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * $Id: IOTypes.hpp,v 1.4 2009-05-13 07:18:17 amaula Exp $
 *
 * \file
 * \brief MaCI - IO Interface Type definition header
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 */
#ifndef _MACI_IOTYPES_HPP_
#define _MACI_IOTYPES_HPP_
#include <inttypes.h>
#include <stdio.h>




namespace MaCI{

  /** MaCI - IO interface
   *
   * This namespace contains all the classes and types related to the IO interface
   * of the MaCI - Machine Control Interface.
   *
   */
  namespace IO{


    /**
     * Type identifiers inside BinBag frame. Used for dynamic encoding/decoding
     * of message frames
     *
     */
    enum EIOType { 
      KTypeUnknown            = -1,  ///< Unknown type
      KTypeDigitalPin         = 0,   ///< Contains state of a dig. pin
      KTypeDigitalBlock       = 1,   ///< Contains state od a dig. pin block (=32 pins)
      KTypeDigitalBlockMask   = 2,
      KTypeAnalogVoltage      = 3,   ///< Contains voltage of a channel
      KTypeTimestamp          = 4,   ///< Contains timestamp
      KTypeCommand            = 5
    };


    /**
     * Commands available (Commands are paired with appropriate following dataelements)
     *
     */
    enum EIOCommand { 
      KCommandUnknown  = -1,  ///< Unknown type
      KCommandGetDigitalPin = 1,
      KCommandGetDigitalBlock = 2,
      KCommandGetAnalogVoltage = 3,
      KCommandSetDigitalPin = 4,
      KCommandSetDigitalBlock = 5,
      KCommandSetAnalogVoltage = 6
      
    };


    /** Pin state information.
     */
    struct TDigitalPinState{
      TDigitalPinState(const int aId=0, const int aState=0):
	id(aId),
	state(aState){}
      
      int32_t id;        ///< Pin/block number
      int32_t state;      ///< pin/block state
    };
    typedef TDigitalPinState TDigitalBlockState;

    
    /** IO Block state information.
     */
    struct TDigitalBlockMask{
      TDigitalBlockMask(const TDigitalBlockState aState=NULL, int aMask=0):
      state(aState),
      mask(aMask){}

      TDigitalBlockState state;       ///< Block state
      int32_t mask;             ///< Mask to operate 
      };
    

    /** Analog IO state information.
     */
    struct TAnalogVoltage{
      TAnalogVoltage(const int aChannel=0, float aVoltage=0):
	channel(aChannel),
	voltage(aVoltage)
      {}
  
      int32_t channel;   ///< Channel of the analog in/output
      float voltage;     ///< Voltage value
    };
   
  
    /** Commands for IO interface
     */
    struct TCommand {
      TCommand(EIOCommand aCmd = KCommandUnknown) 
	: cmd(aCmd) {}
      
      uint32_t cmd; ///< Command \see EIOCommand
    };
    

    /** Information required for reply identification.
     */
    struct TReplyInfo {
      TReplyInfo(int aSenderId=0, int aMsgId=0) :
	senderId(aSenderId),
	msgId(aMsgId){}

      int32_t senderId;
      int32_t msgId;
    };
  }
}

#endif ////< _MACI_IOTYPES_HPP_
